import { AxiosResponse } from "axios";
import dayjs from "dayjs";
import { AggTrades, BookTicker, Depth, Klines, Price, TickerDaily, Trades } from "../model/binance";
import { proxyAxios } from "../utils";
// import axios from "axios";
const axios = proxyAxios()

export interface BinanceApi {
    host: string
    path: string
}

export class MarkApi implements BinanceApi {

    host: string
    path: string

    constructor(host: string, path: string) {
        this.host = host
        this.path = path
    }

    get uri() {
        return `${this.host}${this.path}`
    }

    async price() {
        const { data }: AxiosResponse<Price[]> = await axios.get(`${this.uri}/ticker/price`)
        return data
    }

    async priceParam(symbol: string) {
        const { data }: AxiosResponse<Price[]> = await axios.get(`${this.uri}/ticker/price`, { params: { 'symbol': symbol } })
        return data
    }

    async priceParams(symbols: string[]) {
        const map = new Map<string, Price>()
        let res: Price[] = []
        const price_data = await this.price()
        for (const item of symbols) {
            price_data.filter(data => {
                data.symbol == item ? res.push(data) : ''
            })
        }
        return res
    }

    async exChangeInfo() {
        const { data } = await axios.get(`${this.uri}/exchangeInfo`)
        return data
    }
    async exChangeInfoParam(symbol: string) {
        const { data } = await axios.get(`${this.uri}/exchangeInfo`, { params: { 'symbol': symbol } })
        return data
    }

    async exChangeInfoParams(symbols: string[]) {
        const { data } = await axios.get(`${this.uri}/exchangeInfo`, { params: { 'symbols': JSON.stringify(symbols) } })
        return data
    }

    async depth(req: { symbol: string, limit?: number }) {
        const { symbol, limit = 100 } = req
        const { data }: AxiosResponse<Depth[]> = await axios.get(`${this.uri}/depth`, { params: { 'symbol': symbol, 'limit': limit } })
        return data
    }

    async trades(req: { symbol: string, limit?: number }) {
        const { symbol, limit = 500 } = req
        const { data }: AxiosResponse<Trades[]> = await axios.get(`${this.uri}/trades`, { params: { 'symbol': symbol, 'limit': limit } })
        return data
    }

    async aggTrades(req: { symbol: string, limit?: number, fromId?: number }) {
        const { symbol, limit = 500, fromId } = req
        const { data }: AxiosResponse<AggTrades[]> = await axios.get(`${this.uri}/aggTrades`, { params: { 'symbol': symbol, 'limit': limit, 'fromId': fromId } })
        return data
    }


    async aggTradesByTime(req: { symbol: string, limit?: number, startTime: number, endTime: number }) {
        const { symbol, limit = 500, startTime, endTime } = req
        req.limit = limit
        const { data }: AxiosResponse<AggTrades[]> = await axios.get(`${this.uri}/aggTrades`, { params: req })
        return data
    }

    async avgPriceParam(symbol: string) {
        const { data }: AxiosResponse<AggTrades[]> = await axios.get(`${this.uri}/avgPrice`, { params: { 'symbol': symbol } })
        return data
    }

    async tickerDaily() {
        const { data }: AxiosResponse<TickerDaily[]> = await axios.get(`${this.uri}/ticker/24hr`)
        return data
    }

    async tickerDailyParam(symbol: string) {
        const { data }: AxiosResponse<TickerDaily[]> = await axios.get(`${this.uri}/ticker/24hr`, { params: { 'symbol': symbol } })
        return data
    }

    async tickerDailyParams(symbols: string[]) {
        const arr: TickerDaily[] = []
        const tickerData: TickerDaily[] = await this.tickerDaily()
        for (const item of symbols) {
            tickerData.filter(data => {
                data.symbol == item ? arr.push(data) : ''
            })
        }
        return arr
    }

    async bookTicker() {
        const { data }: AxiosResponse<BookTicker[]> = await axios.get(`${this.uri}/ticker/bookTicker`)
        return data
    }

    async bookTickerParam(symbol: string) {
        const { data }: AxiosResponse<BookTicker> = await axios.get(`${this.uri}/ticker/bookTicker`, { params: { 'symbol': symbol } })
        return data
    }

    async bookTickerParams(symbols: string[]) {
        const arr: BookTicker[] = []
        const bookData: BookTicker[] = await this.bookTicker()
        for (const item of symbols) {
            bookData.filter(data => {
                data.symbol == item ? arr.push(data) : ''
            })
        }
        return arr
    }

    async klines(param: { symbol: string, interval: string, limit?: number }) {
        const { symbol, interval, limit = 500 } = param
        const { data } = await axios.get(`${this.uri}/klines`, { params: { 'symbol': symbol, 'interval': interval, 'limit': limit } })
        return data
    }

    async klinesByTime(param: { symbol: string, interval: string, startTime: number, endTime: number, limit?: number }) {
        const { symbol, interval, startTime, endTime = dayjs().valueOf(), limit = 500 } = param
        let res = await axios.get(`${this.uri}/klines`, { params: { 'symbol': symbol, 'interval': interval, 'limit': limit, 'startTime': startTime, 'endTime': endTime } })
        const data: number[][] = res.data
        return data
    }

    async kinesTime(param: { symbol: string, interval: string, startTime: number, endTime: number, limit?: number }) {
        const arr = []
        const { symbol, interval, startTime, endTime = dayjs().valueOf(), limit = 500 } = param
        let res = await axios.get(`${this.uri}/klines`, { params: { 'symbol': symbol, 'interval': interval, 'limit': limit, 'startTime': startTime, 'endTime': endTime } })
        for (const item of res.data) {
            arr.push(item[0])
        }
        return arr
    }
    async klinesYear(param: { symbol: string, interval: string, startTime: number, endTime: number, limit?: number }) {
        let map = new Map<number, number[]>()
        const { symbol, interval, startTime=1629036800000, endTime = dayjs().valueOf() } = param
        let { data } = await axios.get(`${this.uri}/klines`, { params: { 'symbol': symbol, 'interval': '1M', 'limit': 1000, 'startTime': 0 } })
        for (const item of data) {
            const year = dayjs(item[0]).year()
            const old = map.get(year) || [0, 0, 0, 999999, 999999, 0]
            // console.log(old)
            const open = Math.max(Number(item[1]), Number(old[1]))
            const max = Math.max(Number(item[2]), Number(old[2]))
            const min = Math.min(Number(item[3]), Number(old[3]))
            const close = Math.min(Number(item[4]), Number(old[4]))
            const volume = Number(old[5]) + Number(item[5])
            map.set(year, [year, open, max, min, close, volume])

        }
        let arr = Array.from(map)
        console.log(arr)
        const start = dayjs(startTime).year()
        const end = dayjs(endTime).year()
        
        arr = arr.filter(item=>{
            return item[0] == start || item[0] == endTime
        })
        console.log(arr)
    }
}



